#include "lib/decoders/mod/pvmsourcefactorymod.h"
#include "lib/decoders/mod/pvmvoicesourcemod.h"
#include "lib/decoders/mod/pvmvoicemod.h"
#include "lib/pvmsystem.h"

#include "lib/memory/pvmmemory.h"

PVMSourceFatcoryMOD::PVMSourceFatcoryMOD()
{
}

PVMSourceFatcoryMOD::~PVMSourceFatcoryMOD()
{
}

pvm_bool PVMSourceFatcoryMOD::CanLoad(IPvmInStream* inStream, pvm_int8** /*startData*/, pvm_int* /*startDataSize*/)
{
	pvm_int8 sig[4];
	if(inStream->Seek(1080, EPVM_SEEK_BEGIN)==false)
	{
		inStream->Seek(0, EPVM_SEEK_BEGIN);
		return false;
	}

	if(inStream->Read(sig, 4)!=4)
	{
		inStream->Seek(0, EPVM_SEEK_BEGIN);
		return false;
	}

	inStream->Seek(0, EPVM_SEEK_BEGIN);

	if(PVMVoiceMOD::TranslatePTSign(sig) == 0)
		return false;

	return true;
}

IPVMVoiceSource* PVMSourceFatcoryMOD::CreateVoiceSource(IPvmInStream* inStream, pvm_int8* /*startData*/, pvm_int /*startDataSize*/)
{
	unsigned int modsize;
	unsigned char *mod;

	modsize = (unsigned int)inStream->Size();
	if(modsize<=0)
	{
		inStream->Close();
		return NULL;
	}

	mod = (unsigned char*)PVMMemoryAlloc(modsize);
	if(!mod)
	{
		inStream->Close();
		return NULL;
	}

	inStream->Seek(0, EPVM_SEEK_BEGIN);
	if(inStream->Read(mod, modsize)!=modsize)
	{
		inStream->Close();
        PVMMemoryFree(mod);
        return NULL;
	}

	inStream->Close();

    if (PVMVoiceMOD::TranslatePTSign(((ModHeader *)mod)->mkSign) == 0)
	{
        PVMMemoryFree(mod);
        return NULL;
    }

	PVMVoiceSourceMOD* source = PVMVoiceSourceMOD::Create(mod);

	if(!source)
	{
        PVMMemoryFree(mod);
        return NULL;
	}

	source->AddRef();

	return source;
}

IPVMSourceFatcory* PVMSourceFatcoryMOD::CreateFactory()
{
	return new PVMSourceFatcoryMOD();
}
